package com.jweb.framework.core.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jweb.framework.core.Context;
import com.jweb.framework.core.CoreException;
import com.jweb.framework.core.CoreRegistry;
import com.jweb.framework.core.CoreRuntimeException;
import com.jweb.framework.core.Dispatcher;
import com.jweb.framework.core.Interceptor;
import com.jweb.framework.core.Interceptors;
import com.jweb.framework.core.ProcessExecutor;
import com.jweb.framework.core.Processing;
import com.jweb.framework.core.support.TRACER;
/**
 * 修改人： Thomas
 * 修改内容：新增 
 * 类说明：默认处理分发类
 */
public class DefaultDispatcher implements Dispatcher{

	private static final Logger logger = LoggerFactory.getLogger(DefaultDispatcher.class);
	
	private CoreRegistry coreRegistry ;
	
	private Interceptor interceptors[] ;
	
	/**
	 * @param coreRegistry the coreRegistry to set
	 */
	public void setCoreRegistry(CoreRegistry coreRegistry) {
		this.coreRegistry = coreRegistry;
	}

	/**
	 * @param interceptor the interceptors to set
	 */
	public void setInterceptors(Interceptor[] interceptor) {
		this.interceptors = interceptor;  // 核心拦截器，在所有的交易中全部都会使用到。
	}

	public DefaultDispatcher(){
		
	}
	
	public void dispatch(Context context) throws CoreException,
			CoreRuntimeException {
		
		Processing processing ;
		Interceptor ainterceptor[] ;
		
		Object obj ;
		TRACER.trace("dispatching with context \n {}",new Object[]{context});
		String s = context.getProcessId();
		if(s==null){
			throw new CoreRuntimeException("JAVACO0019","no processId defined in context");
		}
		
		processing = coreRegistry.findProcedure(s);
		context.setProcess(processing);
		String s1 = processing.getInterceptors();
		Interceptors interceptors = coreRegistry.findInterceptors(s1);  //此拦截器是模板内部定义，属于交易级拦截器
		ainterceptor = interceptors.getInterceptors();
		
		int coreSize = -1 ;
		int processSize = -1 ;
		
		obj = null ;
		try {
			
			/**
			 * 核心拦截器
			 */
			if(this.interceptors != null){
				Interceptor[] coreInterceptors = this.interceptors ;
				int coreLen = coreInterceptors.length ;
				
				for(int k=0 ; k < coreLen ; k++){
					Interceptor coreInterceptor = coreInterceptors[k];
					coreSize++ ;
					coreInterceptor.onRequest(context);
				}
			} 
			
			/**
			 * 交易拦截器
			 */
			Interceptor[] processInterceptors = ainterceptor ;
			int processLen = processInterceptors.length ;
			for(int l=0 ; l < processLen ; l++){
				Interceptor processInterceptor = processInterceptors[l];
				processSize++ ;
				processInterceptor.onRequest(context);
			}
			
			String s2 = processing.getExecutor();
			ProcessExecutor processExecutor = coreRegistry.findExecutor(s2);
			processExecutor.execute(context);
			
		} catch (CoreException ce) {
			obj = ce;
            throw ce;
		} 
        catch(CoreRuntimeException cre)
        {
            obj = cre;
            throw cre;
        }
        catch(RuntimeException re)
        {
            obj = re;
            throw re;
        }
        catch(Error error)
        {
            obj = error;
            throw error;
        } 
        finally {
        	
        	/**
        	 * 交易拦截器
        	 */
        	for(int l1 = processSize ; l1 >= 0 ; l1--){
        		Interceptor processInterceptor = ainterceptor[l1];
        		processInterceptor.onResponse(context , (Throwable)obj);
        	}
        	
        	/**
        	 * 核心拦截器
        	 */
        	if(this.interceptors != null){
        		for(int k1 = coreSize ; k1 >= 0 ; k1--){
        			Interceptor coreInterceptor = this.interceptors[k1];
        			coreInterceptor.onResponse(context , (Throwable)obj);
        		}
        	}
        	if(obj!=null){
            	handleExeception((Throwable) obj);
            }
        }
	}
	
	protected void handleExeception(Throwable throwable){
		logger.error("dispatcher error dump .... " , throwable);
	}
}
